/**
 * @Author: lzfto
 * 练习最简单的rust结构体
 * 1.struct是类似pascal struct的东西，外形上和java17之后的record类似
 * 2.定义struct目前有两种方式。分别是属性名，和不带属性名（元组)
 * 3.实例化struct有3中方式：
 *    a.指定属性逐一赋值
 *    b.双点号复制
 *    c.不指定属性赋值（参数名同属性名）
 */


 //有属性的时候，必须是{},必要分号
//元组方式定义的时候，必须是(),且需要分号
struct Point{x:f64,y:f64}
struct Triangle(Point,Point,Point);

//rust允许定义没有成员的空结构体。
#[derive(Debug)]
struct NoItem; 
struct NoItem2();

/**
 * 家庭结构体s
 */
struct Family {
    name: String,
    father: String,
    mather: String,
    children: Vec<String>,
}
/**
 * 这都什么狗屎语法。
 */
struct Book<'a> {
    name: &'a str,
    author: &'a str,
    price: f64,
    pubyear: i32,
}


fn main() {
    let mut family = Family {
        name: String::from("家"),
        father: String::from("爸爸"),
        mather: String::from("妈妈"),
        children: vec![],
    };

    family.children.push(String::from("老大-独龙"));
    family.children.push(String::from("老二-独眼"));
    family.children.push(String::from("老三-独秀"));
    family.children.push(String::from("老四-嘟嘟"));
    family.children.push(String::from("老五-杜牧"));

    //打印家庭结构体
    println!(
        "家庭:{},父亲:{},母亲:{}",
        family.name, family.father, family.mather
    );
    for child in &family.children {
        println!("孩子:{}", child);
    }


    let mut 三国演义 = Book {
        name: "三国演义",
        author: "罗贯中",
        price: 29.8,
        pubyear: 1300,
    };
    
    //各种创建结构实例的方式
    // 方式一：双点号复制
    let mut 红楼梦=Book{
        name:"红楼梦",
        author:"曹雪芹",
        ..三国演义
    };
    //方式二: 略属性名
    let 西游记=write_book("西游记","吴承恩",24.0,1525);
    //方式三:使用基于元组定义的。 比java的record还简单

    let books=[三国演义,红楼梦,西游记];
    for i in 0..books.len() {
        print_book(&books[i]);
    }
    let p1=Point{x:10.0,y:20.0};
    let p2=Point{x:20.0,y:20.0};
    let p3=Point{x:20.0,y:10.0};
    let t=Triangle(p1,p2,p3);
    print_triangle(&t);

    // 测试
    let nod=NoItem{};
    println!("空结构体:{:?}",nod);
}

fn print_book(book:&Book){
    println!(
        "书名:{},作者:{},价格:{},出版年:{}",
        book.name, book.author, book.price, book.pubyear
    );
}

fn print_triangle(t:&Triangle){
    println!("三点坐标:");
    println!("{},{}",t.0.x,t.0.y);
    println!("{},{}",t.1.x,t.1.y);
    println!("{},{}",t.2.x,t.2.y);
}

fn write_book<'a>(name:&'a str,author:&'a str,price:f64,pubyear:i32)->Book<'a>{
    Book{
        name,
        author,
        price,
        pubyear
    }
}
